package com.huiminpay.transaction.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.util.AmountUtil;
import com.huiminpay.common.cache.util.EncryptUtil;
import com.huiminpay.common.cache.util.PaymentUtil;
import com.huiminpay.merchant.dto.AppDTO;
import com.huiminpay.merchant.service.IAppService;
import com.huiminpay.merchant.service.IMerchantService;
import com.huiminpay.paymentagent.api.conf.AliConfigParam;
import com.huiminpay.paymentagent.api.dto.AlipayBean;
import com.huiminpay.paymentagent.api.dto.PaymentResponseDTO;
import com.huiminpay.paymentagent.api.service.IPayAgentService;
import com.huiminpay.transaction.api.dto.OrderResultDTO;
import com.huiminpay.transaction.api.dto.PayChannelParamDTO;
import com.huiminpay.transaction.api.dto.PayOrderDTO;
import com.huiminpay.transaction.api.dto.QRCodeDto;
import com.huiminpay.transaction.convert.PayOrderConvert;
import com.huiminpay.transaction.entity.PayOrder;
import com.huiminpay.transaction.mapper.PayOrderMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.time.LocalDateTime;

@Service
public class TransactionServiceImpl implements ITransactionService {
    @Value("${huiminpay.payUrl}")
    private String payUrl;
    @Reference
    private IAppService appService;
    @Reference
    private IMerchantService merchantService;
    @Reference
    IPayChannelService payChannelService;
    @Autowired
    PayOrderMapper payOrderMapper;
    @Reference
    IPayAgentService payAgentService;

    @Override
    public String createStoreQRCode(QRCodeDto qrCodeDto) throws BusinessException {
        // 校验参数
        if(!appService.queryAppInMerchant(qrCodeDto.getAppId(), qrCodeDto.getMerchantId())){
            //校验应用
            throw new BusinessException(CommonErrorCode.E_200233);
        }

        if(!merchantService.queryStoreInMerchant(qrCodeDto.getStoreId(), qrCodeDto.getMerchantId())){
            // 校验门店
            throw new BusinessException(CommonErrorCode.E_200233);
        }



        // 入口URL+参数  htttp://shouqianba.com/qr/ausiness5xsption
        PayOrderDTO payOrderDTO = new PayOrderDTO();
        payOrderDTO.setStoreId(qrCodeDto.getStoreId());
        payOrderDTO.setAppId(qrCodeDto.getAppId());
        payOrderDTO.setSubject(qrCodeDto.getSubject());
        payOrderDTO.setBody(qrCodeDto.getBody());

        // 对象转json
        String paramsJson = JSON.toJSONString(payOrderDTO);

        String s = EncryptUtil.encodeUTF8StringBase64(paramsJson);
        // http://192.168.137.5:56050/transaction/qr/sdgsdgreyreyeryre
        return payUrl+s;
    }

    @Override
    public String createAlipayWapOrder(PayOrderDTO payOrderDTO) {

        String payChannel = "ALIPAY_WAP";//支付渠道编码
        String tradeNo = PaymentUtil.genUniquePayOrderNo();
        String channel = "huimin_c2b";//服务类型编码  HUIMIN_C2B

        // 为了获取merchantId
//        AppDTO appDTO = appService.myAppInfo(payOrderDTO.getAppId());
//        Long merchantId = appDTO.getMerchantId();
        // 获取支付渠道参数
        PayChannelParamDTO payChannelParamDTO = getPayChannelParamDTO(payOrderDTO, payChannel, channel);
        String param = payChannelParamDTO.getParam();
        if(StringUtils.isBlank(param)){
            throw new BusinessException(CommonErrorCode.CUSTOM);
        }
        AliConfigParam aliConfigParam = JSON.parseObject(param, AliConfigParam.class);
        String payChannelMchAppId = aliConfigParam.getAppId();
        Long merchantId = payChannelParamDTO.getMerchantId();

        // 1.下单（组合参数，保存订单）
        createPayOrder(payOrderDTO, payChannel, tradeNo, channel, payChannelMchAppId, merchantId);


        // 2. 调用代理服务请求三方SDK

        //  2.1 获取支付渠道参数

        //  2.2 调用代理服务
        PaymentResponseDTO<String> payOrderByAliWAP = doAliPayAgent(payOrderDTO, tradeNo, aliConfigParam);
        return payOrderByAliWAP.getContent();
    }

    @Override
    public OrderResultDTO selectPayOrderByOrderNo(String out_trade_no) {
        QueryWrapper<PayOrder> qw = new QueryWrapper<>();
        qw.lambda().eq(PayOrder::getTradeNo,out_trade_no);
        PayOrder payOrder = payOrderMapper.selectOne(qw);

        return PayOrderConvert.INSTANCE.entity2dto(payOrder);
    }

    @Override
    public void updatePayorder(OrderResultDTO orderResultDTO) {
        PayOrder payOrder = PayOrderConvert.INSTANCE.dto2entity(orderResultDTO);
        payOrderMapper.updateById(payOrder);
    }

    private PayChannelParamDTO getPayChannelParamDTO(PayOrderDTO payOrderDTO, String payChannel, String channel) {
        PayChannelParamDTO payChannelParamDTO = payChannelService.queryParamByAppPlatformAndPayChannel(payOrderDTO.getAppId(), channel, payChannel);
        if(payChannelParamDTO==null){
            throw new BusinessException(CommonErrorCode.CUSTOM);
        }
        return payChannelParamDTO;
    }

    private PaymentResponseDTO<String> doAliPayAgent(PayOrderDTO payOrderDTO, String tradeNo, AliConfigParam aliConfigParam) {
        AlipayBean alipayBean = new AlipayBean();
        alipayBean.setOutTradeNo(tradeNo);
        alipayBean.setSubject(payOrderDTO.getSubject());
        Integer totalAmount = payOrderDTO.getTotalAmount();
        String total = null;
        try {
            total = AmountUtil.changeF2Y(String.valueOf(totalAmount));
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(CommonErrorCode.CUSTOM);
        }
        alipayBean.setTotalAmount(total);//
        return payAgentService.createPayOrderByAliWAP(aliConfigParam, alipayBean);
    }

    private void createPayOrder(PayOrderDTO payOrderDTO, String payChannel, String tradeNo, String channel, String payChannelMchAppId, Long merchantId) {
        OrderResultDTO orderResultDTO = PayOrderConvert.INSTANCE.request2dto(payOrderDTO);
        PayOrder payOrder = PayOrderConvert.INSTANCE.dto2entity(orderResultDTO);
        payOrder.setTradeNo(tradeNo);//交易编号
        payOrder.setOutTradeNo(tradeNo);// 外部交易号改成三方的交易号
        payOrder.setMerchantId(merchantId);//
        payOrder.setPayChannel(payChannel);
        payOrder.setPayChannelMchAppId(payChannelMchAppId);
        payOrder.setChannel(channel);
        payOrder.setCurrency("CNY");
        /**
         * 交易状态支付状态,0-订单生成,1-支付中(目前未使用),2-支付成功,3-业务处理完成,4-关闭
         */
        payOrder.setTradeState("0");
        payOrder.setCreateTime(LocalDateTime.now());
        payOrder.setUpdateTime(LocalDateTime.now());
        payOrderMapper.insert(payOrder);
    }
}
